import BaseStation from '../entities/BaseStation'
import WorkerPool from '../entities/WorkerPool'
import workerPool from '../entities/WorkerPool'
import { StationStatus } from '../types'

class Dispatcher {
  //空闲设备
  public idleStations = new Set<BaseStation>()
  //阻塞设备
  private blockedStations = new Set<BaseStation>()
  //特殊设备
  private specialStations = new Set<BaseStation>()
  //清理状态设备
  private clearStations = new Set<BaseStation>()
  //故障设备
  private faultStations = new Set<BaseStation>()
  //工人池
  public workerPoolList = new Set<workerPool>()

  registerStation(station: BaseStation) {
    // 可选：记录拓扑、分组、类别等
  }

  // 注册空闲基站
  registerIdleStation(stations: BaseStation[]) {
    // 遍历基站数组
    stations.forEach((station) => {
      // 将基站添加到空闲基站集合中
      this.idleStations.add(station)
    })
  }

  // 注册特殊基站
  registerSpecialStation(station: BaseStation) {
    this.specialStations.add(station)
  }

  // 注册工人池
  registerWorkerPool(workerPool: workerPool) {
    this.workerPoolList.add(workerPool)
  }

  /**
   * 有设备状态发生改变时，通知调度器
   * @param station
   * @param status
   */
  notifyStatusChange(station: BaseStation, status: StationStatus) {
    this.removeFromAllSets(station)

    if (status === 'idle') this.idleStations.add(station)
    if (status === 'block') this.blockedStations.add(station)
    if (status === 'clearance') this.clearStations.add(station)
    if (status === 'fault') this.faultStations.add(station)

    this.tryResolve()
  }

  /**
   * 尝试解决堵塞和空闲设备
   */
  tryResolve() {
    /**
     * 解决堵塞设备，将产品流入到下一站
     */
    for (const producer of this.blockedStations) {
      if (producer.nextStations) {
        for (const consumer of producer.nextStations) {
          if (this.idleStations.has(consumer) || this.specialStations.has(consumer)) {
            producer.tryDispatchCurrentProduct()
            break
          }
        }
      }
    }

    /**
     * 解决空闲设备，向上游索要产品
     */
    for (const consumer of this.idleStations) {
      if (consumer.prevStations) {
        for (const supplier of consumer.prevStations) {
          if (this.blockedStations.has(supplier) || this.specialStations.has(supplier)) {
            supplier.tryDispatchCurrentProduct()
            break
          }
        }
      }
    }

    /**
     * 解决需要清理的设备，向工人池发送请求
     */
    for (const alarm of this.clearStations) {
      let workerPool = null as null | WorkerPool
      for (const pool of this.workerPoolList) {
        if (pool.isDeviceInMap(alarm.id)) {
          workerPool = pool
          break
        }
      }
      if (workerPool) {
        workerPool.receiveTask('clean', alarm)
      }
    }

    /**
     * 解决故障设备，向工人池发送请求
     */
    for (const fault of this.faultStations) {
      let workerPool = null as null | WorkerPool
      for (const pool of this.workerPoolList) {
        if (pool.isDeviceInMap(fault.id)) {
          workerPool = pool
          break
        }
      }
      if (workerPool) {
        workerPool.receiveTask('maintenance', fault)
      }
    }
  }

  //把某台设备从状态集合中删除
  private removeFromAllSets(station: BaseStation) {
    this.idleStations.delete(station)
    this.blockedStations.delete(station)
    this.clearStations.delete(station)
    this.faultStations.delete(station)
  }

  //清除某台设备的负面状态
  clearNegativeStatus(station: BaseStation) {
    this.clearStations.delete(station)
    this.faultStations.delete(station)
  }

  //清空所有数据
  clear() {
    this.idleStations.clear()
    this.blockedStations.clear()
    this.clearStations.clear()
    this.faultStations.clear()
    this.specialStations.clear()
  }

  //判断某个设备是否在堵塞站里面或者在特殊站里面
  isDeviceInBlockOrSpecial(station: BaseStation) {
    return this.blockedStations.has(station) || this.specialStations.has(station)
  }
}

export const dispatcher = new Dispatcher()
